#include <string.h>
#include "drv_i2c.h"
#include "bus_i2c.h"
#include <math.h>
#include "pwm.h"
#include "main.h"
#include <rtthread.h>

BUS_DATA ipmi_data;
REPORT_DATA report_data;

static void send_report_data(uint32_t i2c_periph, uint8_t recv_addr, uint8_t *recv_buf, uint8_t report_data_value)
{
    int ret;
    report_data.reply[0] = report_data_value;
    report_data.reply[1] = 0x00;
    report_data.reply[2] = 0x00;
    report_data.check_sum = 0 - (ipmi_data.slave_add + recv_buf[3] + recv_buf[4] + 0x00 + report_data_value + 0x00 + 0x00);

    i2c_init_data(i2c_periph, I2C_MASTER_CH, recv_addr);
    ret = i2c_master_send(i2c_periph, recv_addr, (uint8_t *)&report_data, sizeof(report_data));
    if (ret)
    {
        printf("%s: i2c_master_send error!\r\n", __FUNCTION__);
    }
    i2c_init_data(i2c_periph, I2C_SLAVE_CH, ipmi_data.slave_add);
}

static void send_cmd15_report_data(uint32_t i2c_periph, uint8_t recv_addr, uint8_t *recv_buf, uint8_t report_data_value)
{
    int ret, send_len = 0;
    uint8_t buff[128] = {0};
    report_data.reply[0] = report_data_value;
    report_data.check_sum = 0 - (ipmi_data.slave_add + recv_buf[3] + recv_buf[4] + 0x00 + report_data_value + 0x00 + 0x00);

    send_len = sizeof(REPORT_DATA) - (24 - 1); // 3表示reply的个数
    memcpy(buff, (void *)&report_data, send_len);
    buff[send_len - 1] = report_data.check_sum;

    i2c_init_data(i2c_periph, I2C_MASTER_CH, recv_addr);
    ret = i2c_master_send(i2c_periph, recv_addr, buff, send_len);
    if (ret)
    {
        printf("%s: i2c_master_send error!\r\n", __FUNCTION__);
    }
    i2c_init_data(i2c_periph, I2C_SLAVE_CH, ipmi_data.slave_add);
}

static void reply_fan_data(uint8_t *recv_buf, uint32_t i2c_periph)
{
    int ret;
    uint8_t recv_addr = recv_buf[2];
    uint8_t sensor_id = recv_buf[5];
    uint8_t cmd = recv_buf[4];

    report_data = (REPORT_DATA){
        .NetFn = recv_buf[0],
        .head_check_sum = 0 - (recv_buf[0] + recv_addr),
        .src_addr = ipmi_data.slave_add,
        .req_num = recv_buf[3],
        .cmd_code = recv_buf[4],
        .state = (GetFreq() == 0) ? 0x01 : 0x00, // complete state(data ready?)
    };
#if 0
    printf("recv main board addr = 0x%02x!\r\n", recv_addr);
    printf("report_data.NetFn = 0x%02x, report_data.head_check_sum = 0x%02x\r\n,\
                report_data.src_addr = 0x%02x, report_data.req_num = 0x%02x\r\n,\
                report_data.cmd_code = 0x%02x, report_data.state = 0x%02x\r\n,\
                report_data.reply[0] = 0x%02x, report_data.reply[1] = 0x%02x\r\n,\
                report_data.reply[2] = 0x%02x, report_data.check_sum = 0x%02x\r\n",\
                report_data.NetFn, report_data.head_check_sum,\
                report_data.src_addr, report_data.req_num,\
                report_data.cmd_code, report_data.state,\
                report_data.reply[0], report_data.reply[1],\
                report_data.reply[2], report_data.check_sum);
#endif
    if (cmd == 0x15)
    {
        printf("report fan CTRL speed!\r\n");
        send_cmd15_report_data(i2c_periph, recv_addr, recv_buf, 0x03); // 固定值
        // send_report_data(i2c_periph, recv_addr, recv_buf, 0x03);
    }
    else
    {
        switch (sensor_id)
        {
        case 0x00: // fan0
        case 0x01: // fan1
        case 0x02: // fan2
        case 0x03: // fan3
        case 0x04: // fan4
        case 0x05: // fan5
        case 0x06: // fan6
            break;

        default:
            printf("recv invalid sensor number!\r\n");
            break;
        }
    }
}

void i2cbus_thread_entry(void *arg)
{
	uint32_t i2c_periph = (uint32_t)arg;
	rt_mq_t i2c_mq = (i2c_periph == I2C1) ? i2c1_mq : i2c0_mq;
	uint8_t buf[128];
	uint8_t i;

	while (1)
	{
		if (rt_mq_recv(i2c_mq, &buf, sizeof(buf), RT_WAITING_FOREVER) == RT_EOK)
		{
#if 1
			rt_kprintf("I2C%d recv: ", (i2c_periph == I2C1) ? 1 : 0);
			for (i = 0; i < 16; i++)
				rt_kprintf("%02x ", buf[i]);
			rt_kprintf("\n");
#endif

			uint8_t cmd = buf[4];

			switch (cmd)
			{
			case 0x36:
				break;

			case 0x20:
				break;

			case 0x21:
				break;

			case 0x22:
				break;

			case 0x2d:
				break;

			default:
				rt_kprintf("recv invalid cmd_type=%02x, drop!\n", buf[0]);
				continue;
			}
		}
	}
}

int bus_start(uint32_t i2c_periph)
{
	rt_thread_t tid;
    if (i2c_periph == I2C0)
    {
		i2c0_mq = rt_mq_create("i2c0mq", 128, 10, RT_IPC_FLAG_FIFO);
		if (i2c0_mq == RT_NULL)
		{
			rt_kprintf("rt_mq_create() failed.\n");
		}

		tid = rt_thread_create("i2c0_ip", i2cbus_thread_entry, (void *)I2C0, 4096, 4, 20);
		if (tid != RT_NULL)
		{
			rt_thread_startup(tid);
		}

        i2c_reset_rx_data(i2c_periph);

        /* enable the I2Cx interrupt */
        i2c_interrupt_enable(i2c_periph, I2C_INT_ERR);
        i2c_interrupt_enable(i2c_periph, I2C_INT_EV);
        i2c_interrupt_enable(i2c_periph, I2C_INT_BUF);
    }

    if (i2c_periph == I2C1)
    {
		i2c1_mq = rt_mq_create("i2c1mq", 128, 10, RT_IPC_FLAG_FIFO);
		if (i2c1_mq == RT_NULL)
		{
			rt_kprintf("rt_mq_create() failed.\n");
		}

		tid = rt_thread_create("i2c1_ip", i2cbus_thread_entry, (void *)I2C1, 4096, 5, 20);
		if (tid != RT_NULL)
		{
			rt_thread_startup(tid);
		}

        i2c_reset_rx_data(i2c_periph);

        /* enable the I2Cx interrupt */
        i2c_interrupt_enable(i2c_periph, I2C_INT_ERR);
        i2c_interrupt_enable(i2c_periph, I2C_INT_EV);
        i2c_interrupt_enable(i2c_periph, I2C_INT_BUF);
    }

    return 0;
}
